//
// Created by Tony on 2024/5/18.
//

#ifndef LEXER_TOKEN_H
#define LEXER_TOKEN_H

#include <cstdint>
#include <sstream>
#include <string>

namespace Lexer {

using std::string;

enum class TokenType {
    UNKNOWN,
    EOF_T,
    INT64_LITERAL,
    FLT64_LITERAL,
    BOOLEAN_LITERAL,
    CHAR_LITERAL,
    STRING_LITERAL,
    NULL_LITERAL,
    NAME,
    PUNCT,
};

struct Position {
    uint16_t lineNo; // 计数从第1行开始，0代表无效行号
    uint16_t start;  // 计数从0开始
    uint16_t length;

    string startStr() const {
        std::stringstream ss;
        ss << "<" << lineNo << ":" << start << ">";
        return ss.str();
    }

    string endStr() const {
        std::stringstream ss;
        ss << "<" << lineNo << ":" << start + length << ">";
        return ss.str();
    }
};

class Token {
    Position position;

public:
    virtual ~Token() = default;

    explicit Token(const Position& position) : position(position) {}

    Position getPosition() const { return position; }

    virtual TokenType type() = 0;

    virtual string toString() = 0;
};

} // namespace Lexer

#endif // LEXER_TOKEN_H
